package pub.cleangao.mybatis.dao;


import pub.cleangao.mybatis.runtime.MybatisContext;
import java.util.Objects;

/**
 * 具备CRUD的mapper
 *
 * @param <E> 实体类，如：Student
 * @param <I> 主键类型，如：Long，Integer
 */
public interface CrudMapper<E, I> extends
        CreateMapper<E, I>,
        RetrieveMapper<E, I>,
        UpdateMapper<E>,
        DeleteMapper<E, I> {

    /**
     * 保存或修改
     * <p>非空字段</p>
     *
     * @param entity 实体类
     * @return 受影响行数
     */
    default int saveOrUpdate(E entity) {
        Objects.requireNonNull(entity, "parameter `entity` can not be null");
        Object pkValue = MybatisContext.getPkValue(entity);
        // 如果存在数据，执行更新操作
        if (pkValue != null) {
            String pkColumnName = MybatisContext.getPkColumnName(entity.getClass());
            Object columnValue = getColumnValue(pkColumnName, new Query().eq(pkColumnName, pkValue), Object.class);
            if (columnValue != null) {
                return this.update(entity);
            }
        }
        this.save(entity);
        return 1;
    }

    /**
     * 保存或修改
     *
     * <p>全部字段</p>
     *
     * @param entity 实体类
     * @return 受影响行数
     */
    default int saveOrUpdateAllFields(E entity) {
        Objects.requireNonNull(entity, "entity can not null");
        Object pkValue = MybatisContext.getPkValue(entity);
        // 如果存在数据，执行更新操作
        if (pkValue != null) {
            String pkColumnName = MybatisContext.getPkColumnName(entity.getClass());
            Object columnValue = getColumnValue(pkColumnName, new Query().eq(pkColumnName, pkValue), Object.class);
            if (columnValue != null) {
                return this.updateAllFields(entity);
            }
        }
        this.saveAllFields(entity);
        return 1;
    }

}
